package junk;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.ArrayList;


import processing.core.PApplet;
import processing.core.PFont;

public class Main1 extends PApplet {

	private static final long serialVersionUID = 1L;
	public static float innerRadius;
	public static float outerRadius;
	public static float LEVELS = 1;
	public static double expressionCutoff, pValueCutoff, bundlingStrength;
	public static double oldCutoff;
	public static String currentCutoff = "pValue";
	public static String[] annotationOrder = {"Chromosome", "Origins","Stress","Cell Cycle","DNA Damage", "Pheremone"};
	public static String[][] annotationSubGroups = {{"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","None"},{"3'","5'","overlap","None"},{"Up", "Down", "None"},{"M/G1", "G1", "G2/M", "S/G2", "S","None"},{"Up", "Down", "None"}, {"Up", "Down", "None"}};
	public static int[] annotationColumn = {21,8,5,7,18,6};
	public static String[] proteinGroups = {"Control", "HP", "MD", "HOSVD", "OriginHOSVD","Translatome","H202_HI", "H202_LOW", "PROTEIN_A", "PROTEIN_B", "PROTEIN_C", "PROTEIN_D", "PROTEIN_E", "CELL_CYCLE", "OXIDATIVE_STRESS", "PHEREMONE_RESPONSE", "STB5", "REPLICATION_INITIATION"};
	public static int[] proteinGroupsSize = {7,7,7,7,7,12,39,27,31,38,43,58,33,8,7,3,1,4};
	public static int proteinGroup = 0;
	public static Annotations firstAnnotation;
	public static boolean isolate = false;
	public static boolean expandPopup = false;
	public static boolean updateRings;
	public static String showProteins = "Eigenarray";
	public static PFont font10, font12, font14, font15, font18, font32, font48, font;
	public static Gene selectedGene;
	public static Protein selectedProtein;
	public static int xTranslate;
	public static boolean loop;
	public static boolean booleanGroupPopup = false;
	public static boolean uniformGeneSize = true;
	public static Annotations annotationPopup;
	public static MoveObject activeItem;
	public static ArrayList<MoveObject> inactiveItems;
	public static float angleOffset = 0;
	public static Protein bool1, bool2;
	public static Protein newAnnotationGroup;
	public static boolean b1, b2, b3, b4, b5, b6, b7, b8, b9, b10; 
	public static Protein ringProtein;
	public static boolean fractionExpression = false;
	public static boolean newAnnotationPopup = false;
	public static boolean percentValues = false;
	public static int[] groupCutoff = {10,25,75,90};
	public static float[] groupCutoffRaw;
	public static String[] names;
	public static int activeSlider = -1;
	public static boolean resized = false;
	Popups popups;
	Events events;
	Backend backend;
	public float oldWidth = screen.width;
	public static boolean lighter = false;
	public static int scrollBar = 0;
	public final static float WIDTH1 = 2000f;
	public final static float HEIGHT1 = 1435f;
	public static float xTranslate1;
	public static boolean frontEnd  = true;
	
	//Initialize variables
	public void Main1() {
		//size(1024,768);
		smooth();
		frameRate(30);
		expressionCutoff  = .002;
		pValueCutoff = .01;
		bundlingStrength = .86;
		innerRadius = (float)height*.3f;
		outerRadius = (float)height*.35f;
		xTranslate = (int)(width*.07);
		xTranslate1 = (WIDTH1/width)*xTranslate;
		updateRings = true;
		popups = new Popups();
		events = new Events();
		backend = new Backend();		
		initFonts();
		new ReadGenes( this);
		ringProtein = Protein.proteinList[0];
		firstAnnotation = new Annotations(annotationOrder[0],"All", "All", Gene.geneList, this, 1);
		Annotations.setCenterRadius();
		inactiveItems = new ArrayList<MoveObject>();
		loop = false;		
		noLoop();	
		scale((float)width/screen.width, (float)height/screen.height);
		
	}
	public void draw() {
		System.out.println(activeItem);
		float start = millis();
		status(Integer.toString(frameCount));
		if(!mousePressed) cursor(WAIT);
		ellipseMode(CENTER);
		innerRadius = (float)height*.4f;
		outerRadius = (float)height*.47f;
		xTranslate = (int)(width*.07);
		Annotations.setCenterRadius();
		translate(width/2-xTranslate, height/2);
		background(0);		
		if(frontEnd)
		{
			firstAnnotation.drawGroup((float)Math.PI/2 - angleOffset, (float)(3*Math.PI/2) + angleOffset, 1, "All");
			
			fill(0);
			arc(0f, 0f, Main1.innerRadius*2, Main1.innerRadius*2,  0f, (float)(2*Math.PI));  //fills in center black
			for( Gene gene: firstAnnotation.genes)   //draws all of the active genes
			{
				/*
				if(gene.active)
					gene.drawGene();
					*/
			}
			Protein.findProteins();								//finds and sets coordinates of proteins
			if(activeItem instanceof Annotations) activeItem.drawMe(true);
			for(MoveObject inactiveItem: inactiveItems)
				if(inactiveItem instanceof Annotations) inactiveItem.drawMe(false);
			else updateRings = false;
			Protein.drawProteins();
			loadDisplay();	
			if(booleanGroupPopup) popups.booleanGroupPopup(this);
			if(newAnnotationPopup) popups.newAnnotationPopup(this);
		}
		else
		{
			backend.initialize(this);
		}
		println(millis()-start);
		cursor(ARROW);
		
		if(loop) loop();
		else noLoop();
		oldWidth = width;
		if(lighter) darken();
	}
	
	public static void main (String args[])
    {
    	PApplet.main (new String[] {
    			Main1.class.getName() });
    }
	
	public void mouseClicked()
	{
		events.mouseClickedEvent(this);
		scale(2000f/width, 1435f/height);
	}
	public void mousePressed()
	{
		events.mousePressedEvent(this);
		scale(2000f/width, 1435f/height);
	}
	public void mouseDragged()
	{
		events.mouseDraggedEvent(this);
		scale(2000f/width, 1435f/height);
	}
	public void mouseReleased()
	{
		events.mouseReleasedEvent(this);
		scale(2000f/width, 1435f/height);
	}
	public void keyPressed()
	{
		events.keyPressedEvent(this);
		scale(2000f/width, 1435f/height);
	}
	
	//displays all of the text and supporting information
	public void loadDisplay() {
		scale(width/WIDTH1, height/HEIGHT1);
		loadDisplayCutoffs();
		loadDisplayPopups();
		loadDisplayAnnotations();
		loadDisplayTable();
		scale(WIDTH1/width, HEIGHT1/height);
	}
	public void loadDisplay2() {
								
		scale(width/WIDTH1, height/HEIGHT1);
		loadDisplayTable();
		scale(WIDTH1/width, HEIGHT1/height);
	}
	public void loadDisplayCutoffs() {
		rectMode(CENTER);
		int color = color(128,128,20);
		if(lighter) fill(Main1.blendColor(color(255),color(color), SUBTRACT));
		else fill(color);
		textFont(font32);
		text(ringProtein.name, -WIDTH1/2 + xTranslate1 + 20, -HEIGHT1/2 + 100);
		textFont(font18);
		//display parameter information
		if(currentCutoff.equals("pValue"))	fill(255,100,100);
		else fill(200);
		text("P-Value Cutoff     " + (double)Math.round(pValueCutoff*1000000)/1000000, WIDTH1/2 + xTranslate1 - 240, -HEIGHT1/2 + 25);
		if(currentCutoff.equals("Expression"))	fill(255,100,100);
		else fill(200);
		text("Expression Cutoff " + (double)Math.round(expressionCutoff*1000000)/1000000, WIDTH1/2 + xTranslate1 - 240, -HEIGHT1/2 + 48);
		if(currentCutoff.equals("Beta"))	fill(255,100,100);
		else fill(200);
		text("Bundling Strength: " + (double)Math.round(bundlingStrength*100)/100, WIDTH1/2 + xTranslate1 - 240, -HEIGHT1/2 + 71);
		textFont(font48);
		color = color(0,50,100);
		if(lighter) fill(Main1.blendColor(color(255),color(color), SUBTRACT));
		else fill(color);
		text(ringProtein.annotation, -WIDTH1/2 + xTranslate1 + 20,-HEIGHT1/2 +70);
		stroke(255);
		noFill();
		rect(-WIDTH1/2 + xTranslate1 + 33, -HEIGHT1/2 + 128, 20, 20);
		if(uniformGeneSize) 
		{
			line(-WIDTH1/2 + xTranslate1 + 23, -HEIGHT1/2 + 118, -WIDTH1/2 + xTranslate1 + 43, -HEIGHT1/2 + 138);
			line(-WIDTH1/2 + xTranslate1 + 43, -HEIGHT1/2 + 118, -WIDTH1/2 + xTranslate1 + 23, -HEIGHT1/2 + 138);
			color = color(0,255,0);
		}
		else color = color(0,255,0,100);
		if(lighter) fill(Main1.blendColor(color(255),color(color), SUBTRACT));
		else fill(color);
		textFont(font14);
		text("Unifrom Gene Size", -WIDTH1/2 + xTranslate1 + 50, -HEIGHT1/2 + 132);
	}
	public void loadDisplayPopups()
	{		
		//popup for user selected gene
		if ( selectedGene != null)
		{
			textFont(font14);
			int color = color(0,128,255);
			if(lighter) fill(Main1.blendColor(color(255),color(color), SUBTRACT));
			else fill(color);
			if(!expandPopup)
			{
				rectMode(CORNER);
				fill(0,0,0,100);
				rect(selectedGene.x1, selectedGene.y1, 200, 50);
				fill(255,255,255);
				String[] details = selectedGene.geneDetails();
				text(details[0], selectedGene.x1 + 5, selectedGene.y1 + 5);
				textFont(font10);
				fill(255,255,220);
				text("more", selectedGene.x1 + 5, selectedGene.y1 + 45);
				fill(255,200,200);
				text("isolate", selectedGene.x1 + 160, selectedGene.y1 + 45);
				fill(255,255,255);
				textFont(font15);
				text("X", selectedGene.x1 + 185, selectedGene.y1 + 13);
				rectMode(CENTER);
			}
			else
			{
				 rectMode(CORNER);
				  fill(0,0,0,100);
				  rect(selectedGene.x1, selectedGene.y1, 400, 150);
				  fill(255,255,255);
				  String[] details = selectedGene.geneDetails();
				  for(int i = 0; i< details.length; i++)
					  text(details[i], selectedGene.x1 + 5, selectedGene.y1 + 5 + 15*i);			  
				  rectMode(CENTER);
			}
		}
	}
	public void loadDisplayAnnotations()
	{
		//annotation information at bottom left of display
		translate(xTranslate1, 0);
		textAlign(CENTER);
		textFont(font12);
		fill(128,255,128);
		
		for(int i = 0; i< firstAnnotation.myLevels; i++)
		{
			float offset = i*150;
			textFont(font18);
			fill(255,255,255);
			rotate(-PI/2);
			textAlign(RIGHT);
			text(annotationOrder[i], -HEIGHT1/2 +310 + offset, -WIDTH1/2 + 19 );
			rotate(PI/2);
			textFont(font12);
			String[] strings = annotationSubGroups[i];
			textAlign(LEFT);
			for (int j = 0; j< strings.length; j++)
			{
				fill(Annotations.generalColor(j));
				if(j<9)
					text(strings[j], -WIDTH1/2 + 40, HEIGHT1/2 - 300 + 13*j - offset);
				else
					text(strings[j], -WIDTH1/2 + 100, HEIGHT1/2 - 300 + 13*(j-9) - offset);
			}
			textAlign(CENTER);
		}
		for(int i = firstAnnotation.myLevels; i< annotationOrder.length; i++)
		{
			float offset = (i- firstAnnotation.myLevels)*75;
			textFont(font18);
			fill(255,255,255);
			rotate(-PI/2);
			textAlign(LEFT);
			text(annotationOrder[i], -HEIGHT1/2 +20, -WIDTH1/2 + 19 + offset);
			rotate(PI/2);
			textFont(font12);
			String[] strings = annotationSubGroups[i];
			textAlign(CENTER);
			text("^", -WIDTH1/2 + 35 + offset, HEIGHT1/2 - 10);
			text("^", -WIDTH1/2 + 35 + offset, HEIGHT1/2 - 50);
			text("^", -WIDTH1/2 + 35 + offset, HEIGHT1/2 - 60);
		}
		textAlign(LEFT);
		translate(-xTranslate1, 0);	
	}
	public void loadDisplayTable()
	{		
		//variable scroll box
		rectMode(CENTER);
		fill(188,188,17,100);
		rect(WIDTH1/2+20 , 0, 200, 1000);		
		int color = color(196,14,29,200);
		fill(color);
		color = color(180,100);
		strokeWeight(3);
		stroke(color);
		roundRect(WIDTH1/2-80, 520, 200, 180);
		fill(255,200);
		textFont(font32);
		text("Manage", WIDTH1/2 - 50, 590);
		text("Data", WIDTH1/2 - 23, 640);
		stroke(255,200);
		strokeWeight(10);
		line(WIDTH1/2 - 25, 660, WIDTH1/2+75 , 660);
		line(WIDTH1/2 + 75, 660, WIDTH1/2+55 , 640);
		line(WIDTH1/2 + 75, 660, WIDTH1/2+55 , 680);
		//draw variable names in table
		Protein protein = Protein.allProteins;
		int listLength = 0;
		for(int i = 0; i< protein.children.size(); i++)
		{
			listLength = listLength + 40;
			if(protein.children.get(i).expand) listLength = listLength + protein.children.get(i).children.size()*20;
		}
		int h = -462;
		if(listLength > (500+462))
		{
			h = h- (int)(.01*scrollBar*listLength);
			strokeWeight(1);
			fill(188,188,17,100);
			rect(WIDTH1/2+125 , 0, 10, 1000);
			fill(0,100);
			rect(WIDTH1/2+125 , (float)(scrollBar*.01*(500+482))-482, 10, 20);
		}
		proteinTable(h, 1, protein);
		strokeWeight(1);
		
		
		if(annotationPopup != null) popups.showAnnotationPopup(annotationPopup, this);
	}
	public int proteinTable(int h, int level, Protein protein1)
	{
		Protein protein = protein1;;
		int lineHeight, space;
		int color;
		if(protein1.children == null) return h;
		for(int i = 0; i< Protein.proteinList.length; i++)
		{
			if(Protein.proteinList[i].toString().equals(protein1.toString()))
			{
				protein = Protein.proteinList[i];
				break;
			}
		}
		for(int i = 0; i< protein.children.size(); i++)
		{
			if(h>500) return h;
			else
			{
				if(level == 1) 
				{
					textFont(font32);
					color = color(255,50);
					lineHeight = 40;
					space = 16;
				}
				else
				{
					textFont(font18);
					color = color(0,0,255,30);
					lineHeight = 20;
					space = 9;	
					h = h-16;
				}
				textLeading(space*2);
				
				int numLines = 1;				
				String s = protein.children.get(i).name;
				if(textWidth(s) > 180)
					if(s.contains("_"))
					{
						s= s.replace("_", "\n");
						numLines ++;
					}
				if( h > -482)
				{
					if(i%2 ==0)
					{
						noStroke();
						fill(color);
						if(numLines ==1)
							rect(WIDTH1/2+20, h-space, 200, lineHeight*numLines);
						else
							rect(WIDTH1/2+20, h, 200, lineHeight*numLines);
					}			
					fill(255,200);
					text(s, WIDTH1/2 - 80, h-space/2);
				}
				protein.children.get(i).tablePosition = h;
				h=h+ (int)(lineHeight*numLines);
				if(level == 2) h= h+16;
				if(protein.children.get(i).expand) h = proteinTable(h, level+ 1, protein.children.get(i));
				
			}
		}
		return h;
	}
	
	public void initFonts() {
		font10 = createFont("FFScala", 10);
		font12 = createFont("FFScala", 12);
		font14 = createFont("FFScala", 14);
		font15 = createFont("FFScala", 15);
		font18 = createFont("FFScala", 18);
		font32 = createFont("FFScala", 32);
		font48 = createFont("FFScala", 48);
	}

	public void roundRect(float x, float y, float w, float h)
	{
	  float corner = w/10.0f;
	  float midDisp = w/20.0f;
	  
	  beginShape();  
	  curveVertex(x+corner,y);
	  curveVertex(x+w-corner,y);
	  curveVertex(x+w+midDisp,y+h/2.0f);
	  curveVertex(x+w-corner,y+h);
	  curveVertex(x+corner,y+h);
	  curveVertex(x-midDisp,y+h/2.0f);
	  
	  curveVertex(x+corner,y);
	  curveVertex(x+w-corner,y);
	  curveVertex(x+w+midDisp,y+h/2.0f);
	  endShape();
	} 
	public void darken() 
	{
		loadPixels();
		for(int i = 0; i< pixels.length; i++)	
		{
			pixels[i] = blendColor(color(255),pixels[i], SUBTRACT);
			pixels[i] = color((red(pixels[i])+green(pixels[i]) + blue(pixels[i]))/3);
		}			
		updatePixels();
		
	}
	
}
